package com.enjoy.adv.server;

import com.enjoy.adv.vo.MessageType;
import com.enjoy.adv.vo.MyHeader;
import com.enjoy.adv.vo.MyMessage;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by HP on 2019/7/19.
 */
public class LoginAuthRespHandler extends ChannelInboundHandlerAdapter{
    private final static Log LOG
            = LogFactory.getLog(LoginAuthRespHandler.class);

    //用以检查用户是否重复登录的缓存
    private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<String, Boolean>();
    //用户登录的白名单
    private String[] whitekList = { "127.0.0.1"};

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        MyMessage message= (MyMessage) msg;
        //是登陆消息 进行处理
        if (message.getMyHeader()!=null&&message.getMyHeader().getType()
                ==MessageType.LOGIN_REQ.getValue()){
            String nodeIndex=ctx.channel().remoteAddress().toString();
            MyMessage loginResp=null;
            //是否重复登录
            if (nodeCheck.containsKey(nodeIndex)){
             loginResp=buildResponse((byte)-1);
            }else{
                //是否白名单，是允许登录，写入缓存
                InetSocketAddress address= (InetSocketAddress) ctx.channel().remoteAddress();
                String ip=address.getAddress().getHostAddress();
                boolean isOk=false;
                for (String wip:whitekList){
                    if (wip.equals(ip)){
                        isOk=true;
                        break;
                    }
                }

                loginResp=isOk?buildResponse((byte)0):buildResponse((byte)-1);
                if (isOk){
                    nodeCheck.put(nodeIndex,true);
                }
                LOG.info("The login response is : " + loginResp
                        + " body [" + loginResp.getBody() + "]");
                ctx.writeAndFlush(loginResp);
                ReferenceCountUtil.release(msg);
            }
        }else{
            //其他消息 继续传递
            ctx.fireChannelRead(msg);
        }
    }


    private MyMessage buildResponse(byte result) {
        MyMessage message = new MyMessage();
        MyHeader myHeader = new MyHeader();
        myHeader.setType(MessageType.LOGIN_RESP.getValue());
        message.setMyHeader(myHeader);
        message.setBody(result);
        return message;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        nodeCheck.remove(ctx.channel().remoteAddress().toString());
        ctx.close();
        ctx.fireExceptionCaught(cause);
    }
}
